
package channel;

import java.io.Serializable;
import java.rmi.RemoteException;

import node.Node;
/**
 * An abstract class for the channel (both virtual channel and actual channel).
 * 
 * @author TCSS 558 Team 6
 * @version Spring 2013
 * 
 */
public abstract class AbstractChannel implements Serializable 
{

  /**
   * 
   */
  private static final long serialVersionUID = 1L;

  /**
   * The channel id (The id of the destination id).
   */
  protected final int my_channel_id;

  /**
   * It is the lower boundary of the interval.
   */
  protected final int my_lower_limit;

  /**
   * It is the upper boundary of the interval.
   */
  protected final int my_upper_limit;
  /**
   * node id.
   */
  protected int my_node;

  /**
   * Constructor. Creates the connection channel for every actual nodes.
   * 
   * @param the_node is the actual node this channels starts at.
   * @param the_number is the k value for the connection channel.
   * @param the_m is the total connections from / to one node.
   * @throws RemoteException if there are problems with the remote call.
   */
  public AbstractChannel(final Node the_node, final int the_number, final int the_m)
    throws RemoteException 
  {
    this(the_node.getMyID(), the_number, the_m);
  }

  /**
   * Constructor of the AbstractChannel.
   * @param the_node node ID.
   * @param the_number 
   * @param the_m m value.
   */
  public AbstractChannel(final int the_node, final int the_number, final int the_m) 
  {
    my_node = the_node;
    my_channel_id = ((1 << the_number) + my_node) % (1 << the_m);
    final int next = ((1 << (the_number + 1)) + my_node) % (1 << the_m);
    my_lower_limit = my_channel_id;
    my_upper_limit = next - 1;
  }

  /**
   * Find it the node is in the range of interval.
   * 
   * @param the_id is the Id of the node.
   * @return true if it is in the range, otherwise false.
   */
  public boolean isInInterval(final int the_id) 
  {
    boolean result = false;
    if (my_lower_limit > my_upper_limit)  
    {
      if (the_id >= my_lower_limit || the_id <= my_upper_limit) 
      {
        result = true;
      }
    } 
    else 
    {
      if (the_id >= my_lower_limit && the_id <= my_upper_limit) 
      {
        result = true;
      }
    }
    return result;
  }

  /**
   * Gets the channel Id.
   * 
   * @return the channel id.
   */
  public int getChannelId() 
  {
    return my_channel_id;
  }

}
